package com.jy.rhin.parse;


import com.jy.rhin.infra.cda.XPath;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author 姚俊
 * @Date 2023/2/14 15:57
 * @Description 解析器工厂
 */
@Component
@Slf4j
public class ParserFactory {

    @Resource
    ApplicationContext context;

    static Map<Class<? extends Selector>, Selector> parserMap = new HashMap<>();

    @PostConstruct
    public void init(){
        for (Map.Entry<String, Selector> entry : context.getBeansOfType(Selector.class).entrySet()) {
            parserMap.put(entry.getValue().getClass(), entry.getValue());
        }
    }

    public static Selector getParser(XPath xPath){
        boolean isListPath = !StringUtils.isBlank(xPath.listItemPath());
        if (isListPath) {
            return getListParser(xPath);
        } else {
            return getObjectParser(xPath);
        }
    }

    private static Selector getObjectParser(XPath xPath){
        String model = xPath.model();
        if (StringUtils.equals("code", model)) {
            return parserMap.get(CodeValueSelector.class);
        }
        if (StringUtils.equals("direct", model)) {
            return parserMap.get(DirectValueSelector.class);
        }
        return parserMap.get(NoneSelector.class);
    }

    private static Selector getListParser(XPath xPath) {
        Class<? extends Selector> selectorClazz = xPath.itemParser();
        if (Objects.nonNull(selectorClazz)) {
            return parserMap.get(selectorClazz);
        } else {
            return getObjectParser(xPath);
        }
    }

}
